#include "TcpConnection.hh"

using std::cout;
using std::endl;
using std::shared_ptr;
using std::string;
using std::to_string;
using std::ref;

TcpConnection::TcpConnection(int fd)
    : _sock_io(fd)
    , _sock(fd)
    , _localAddr(Get_localaddr())
    , _peerAddr(Get_peeraddr()){

}

TcpConnection::~TcpConnection(){

}

InetAddress TcpConnection::Get_localaddr(){
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr);
    if(::getsockname(_sock.Get_fd(), (struct sockaddr*)&addr, &len) == -1){
        error(1, errno, "getsockname");
    }

    return InetAddress(addr);
}

InetAddress TcpConnection::Get_peeraddr(){
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr);
    if(::getpeername(_sock.Get_fd(), (struct sockaddr*)&addr, &len) == -1){
        error(1, errno, "getpeername");
    }

    return InetAddress(addr);
}

void TcpConnection::Send(const string &msg){
    _sock_io.Write_n(msg.c_str(), msg.size());
}

string TcpConnection::Recv(){
    char buf[2048] = {0};
    _sock_io.Read_line(buf, sizeof(buf) - 1);
    return string(buf);
}

string TcpConnection::To_string(){
    return string("localaddr: ") + _localAddr.Get_ip()
    + ": " + to_string(_localAddr.Get_port())
    + " ----> " + "peeraddr: " + _peerAddr.Get_ip() 
    + ": " + to_string(_peerAddr.Get_port());
}

bool TcpConnection::Is_close(){
    char buf[5] = {0};
    int count = ::recv(_sock.Get_fd(), buf, sizeof(buf), MSG_PEEK);
    return (count == 0);
}

void TcpConnection::Set_new_conn(const fun_ptr &new_conn){
    _new_conn = new_conn;
}
void TcpConnection::Set_old_conn(const fun_ptr &old_conn){
    _old_conn = old_conn;
}
void TcpConnection::Set_close_conn(const fun_ptr &close_conn){
    _close_conn = close_conn;
}

void TcpConnection::New_conn(){
    _new_conn(shared_from_this());
}

void TcpConnection::Old_conn(){
    _old_conn(shared_from_this());
}

void TcpConnection::Close_conn(){
    _close_conn(shared_from_this());
}
